﻿// --------------------------------------------------------------------------------------
// <copyright file="SqlUtil.cs" company="NGroup">
// Copyright (c) NGroup. All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------
// <history>
//     <change who="Bui Thanh Nam" date="2013.12.15">Create</change>
// </history>
// --------------------------------------------------------------------------------------

namespace NGroup.VTL.Core.Utilities
{
    using System;
    using System.Data;

    public static class SqlUtil<T>
    {
        public static T GetValue(IDataReader reader, string fieldName)
        {
            if (!HasColumn(reader, fieldName))
            {
                return default(T);
            }

            object value;
            if (reader == null || (value = reader[fieldName]) == DBNull.Value)
            {
                return default(T);
            }

            return (T)CastValue(value);
        }

        public static T GetValue(DataRow drow, string fieldName)
        {
            object value = null;
            if (drow != null && drow.Table.Columns.Contains(fieldName))
            {
                value = CastValue(drow[fieldName]);
            }

            if (value == null || value == DBNull.Value)
            {
                value = default(T);
                if (typeof(T).Name.ToLower() == "string")
                {
                    value = "";
                }
            }

            return (T)value;
        }

        public static T CastValue(object value)
        {
            var type2String = typeof(T).Name.ToLower();
            if (value != null && value != DBNull.Value)
            {
                string valueString = value.ToString();
                switch (type2String)
                {
                    case "string":
                        value = valueString;
                        break;
                    case "int32":
                        int intTmp = 0;
                        int.TryParse(valueString, out intTmp);
                        value = intTmp;
                        break;
                    case "int64":
                        long int64Tmp = 0;
                        Int64.TryParse(valueString, out int64Tmp);
                        value = int64Tmp;
                        break;
                    case "boolean":
                        byte bitValue;
                        if (byte.TryParse(valueString, out bitValue))
                        {
                            value = Convert.ToBoolean(bitValue);
                        }
                        else
                        {
                            value = Convert.ToBoolean(valueString);
                        }
                        break;
                    case "datetime":
                        DateTime dateTmp;
                        DateTime.TryParse(valueString, out dateTmp);
                        value = dateTmp;
                        break;
                    case "float":
                        float floatTmp;
                        float.TryParse(valueString, out floatTmp);
                        value = floatTmp;
                        break;
                    case "decimal":
                        decimal decimalTmp;
                        decimal.TryParse(valueString, out decimalTmp);
                        value = decimalTmp;
                        break;
                    default:
                        break;
                }
            }
            else
            {
                if (type2String == "string")
                    value = "";
                else
                    value = default(T);
            }
            return (T)value;
        }

        private static bool HasColumn(IDataRecord dr, string columnName)
        {
            int drCount = dr.FieldCount;
            for (int i = 0; i < drCount; i++)
            {
                if (dr.GetName(i).Equals(columnName, StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }

            return false;
        }
    }
}
